.686
.model flat, stdcall
option casemap: none
 
include		C:\masm32\include\windows.inc
include		C:\masm32\include\user32.inc
include		C:\masm32\include\kernel32.inc

includelib	C:\masm32\lib\user32.lib
includelib	C:\masm32\lib\kernel32.lib

include		C:\masm32\include\masm32.inc
include		C:\masm32\include\msvcrt.inc
;include		C:\masm32\macros\macros.asm
includelib	C:\masm32\lib\masm32.lib
includelib	C:\masm32\lib\msvcrt.lib


printf		proto	C :dword, :vararg		; msvcrt
ExitProcess proto	STDCALL :DWORD			; kernel32
;print_endline	proto

.const
BSIZE			equ 30   					; так задается константа BSIZE
one				equ 1
two				equ 2
;==================Перевод в строку и печать числа========================
;printConsoleInt MACRO M1
;	LOCAL metka1
;	;invoke	GetStdHandle, -11		;дескриптор вывода
;	push -11
;	call GetStdHandle
;	mov		stdout, eax				;по умолчанию помещается в eax
;	
;	;необходимо очистить buf
;	mov ecx, BSIZE
;	metka1:
;		mov buf[ecx], 0
;		dec ecx
;		CMP eCX , 0
;		jne metka1
;	;==========================
;	;push offset M1
;	;push offset ifmt
;	;push offset buf
;	;call wsprintf
;	invoke	wsprintf, ADDR buf, ADDR ifmt, M1
;	
;	;заполняем последние байты символами перехода на новую строчку
;	mov buf[BSIZE - two], 10			;====\r
;	mov buf[BSIZE - one], 13			;====\n
;	
;	push 0
;	push offset cWritten
;	push BSIZE
;	push offset buf
;	push stdout
;	call WriteConsoleA
;	;invoke	WriteConsoleA, stdout, ADDR buf, BSIZE, ADDR cWritten, 0
;ENDM
;==================================================================
.data
	ifmt			db "%d",0			;строка формата
	buf				db BSIZE dup(?)		;буфер
	msg				dd 123456			;то что мы выводим
	stdout			dd ?
	cWritten 		dd ?
		
	res32			dd 0
	res16			dw ?
	dopres16		dw 0
	res8			db ?
	resDouble		dq 0.0
	
	exDouble1		dq	-16.12523
	exDouble2		dq	78.4545
	
	ex10c1			dt	98.0052
	ex10c2			dt	9.0052
	res10			dt ?
	
	y				dd	-555
	Pi				dq	3.141592
	tpt				db	"%1.10f",0
	floatEx1		dd	4.55
	
	eps				dq	0.1
	minX			dq	-5.0
	maxX			dq	5.0
	endline			db 13,10,0
	
	razdelit		db	50 dup("="),10,0
	formatStr		db	"%s",0
	formatInt		db	"%i",0
	formatShort		db	"%u",0
	
	;=====переменные для расчета суммы или проиведения======
	resSum			dq	0.0
	resPr			dq	1.0
	chisloN			dq	1.0
	increment		dq	1.0
	chislitel		dq	?
	znamenatel		dq	?
.code
start:

	;================Продолжаем расчет для вещественных===============
	;mov ecx,5
	;finit
	;fld exDouble2
	;summaV:
	;	fmul Pi
	;	fstp resDouble
	;	;invoke	crt_printf, ADDR tpt, resDouble
	;	fld resDouble
	;	
	;	DEC eCX
	;	CMP eCX , 0
	;	JNE summaV
	;MOV res, eax
	;printConsoleInt res
	;invoke	crt_printf, ADDR tpt, resDouble
	;fwait

	;invoke	crt_printf, ADDR formatStr, razdelit
	;invoke	crt_printf, ADDR formatStr, razdelit
	;вызов процедуры
	call print_endline
	;add ESP, 8
	;invoke	crt_printf, ADDR formatStr, ADDR razdelit
	;===== сложение двух целых чисел и вывод======
	MOV ebx, -18
	MOV ecx, -257
	add ecx, ebx	
	MOV res32, ecx
	
	push res32
	call print_int
	
	call print_Newline
	;========вычитание двух целых и вывод===========
	MOV ebx, 520
	MOV ecx, 157
	sub ecx, ebx	
	MOV res32, ecx
	
	push res32
	call print_int
	call print_Newline
	;=========целое умножение и вывод=================
	MOV AL, 150    ; Первый множитель в регистр AL
	MOV BL, 250    ; Второй множитель в регистр BL
	MUL BL         ; Теперь АХ = 150 * 250 = 37500
	MOV res16, AX
	
	;mov word ptr [res + 2], 0
	;mov word ptr res, ax
	;push res
	;call print_int
	
	
	;push dopres16						;грузим в стек для вызова printf
	;push res16
	;lea ebx, formatShort
	;push ebx
	;call printf
	
	push res16
	call print_short
	call print_Newline
	;========умножение с большим результатом===========
	MOV AX, 10000  ; Первый множитель в регистр AX
	MOV BX, 5000   ; Второй множитель в регистр BX
	MUL BX         ; Теперь (DX АХ) = 10000 * 5000 = 50000000
	;так как результат умножения в двух регистрах, необходимо их объединить в одно число
	mov word ptr [res32+2],dx
	mov word ptr res32,ax
	push res32
	call print_int
	call print_Newline
	;=========целое деление и вывод====================
	MOV AX, 750   ; Делимое в регистр AX
	MOV BL, 15   	; Делитель в регистр BL
	DIV BL        ; Теперь АL = 250 / 150 = 1, AH = 100
	MOV res8, AL
	
	mov word ptr [res32 + 2], 0
	mov byte ptr [res32 + 1], 0
	mov byte ptr res32, AL
	push res32
	call print_int
	call print_Newline
	;========деление большого числа===========
	MOV DX, word ptr [res32 + 2]	; Делимое - в пару регистров DX AX
	MOV AX, word ptr res32 			; (DX AX) = 50000000
	MOV BX, 6   					; Делитель в регистр BX
	DIV BX							; Теперь АХ = 50000000 / 60000 = 833 (341h) DX = 20000 (4E20h)
	;MOV res2, AX
	
	mov word ptr [res32 + 2], 0
	mov word ptr res32, ax
	push res32
	call print_int
	call print_Newline
	
	;========ОПЕРАЦИИ С ВЕЩЕСТВЕННЫМИ ЧИСЛАМИ=========================
	;===============сложение=======================
	finit
	fld exDouble1
	fadd exDouble2
	fstp resDouble
	fwait
	
	;push offset tpt
	;push offset resDouble
	;call crt_printf
	
	;invoke	crt_printf, ADDR tpt, resDouble
	
	;вычитание
	finit
	fld exDouble1
	fld exDouble2
	fxch st(1)
	fsub Pi
	fstp resDouble
	fwait
	
	;push offset tpt
	;push offset resDouble
	;call crt_printf
	;invoke	crt_printf, ADDR tpt, resDouble
	;умножение
	finit
	fld exDouble1
	fmul exDouble2
	fstp resDouble
	fwait
	;push offset tpt
	;push offset resDouble
	;call crt_printf
	;invoke	crt_printf, ADDR tpt, resDouble
	;деление
	finit
	fld exDouble1
	fld exDouble2
	fdiv st(0), st(1)
	fstp resDouble
	fwait
	;push offset tpt
	;push offset resDouble
	;call crt_printf
	;invoke	crt_printf, ADDR tpt, resDouble
	;================Начинаем расчет===============
	mov ecx,115
	mov eax,00
	summa:
		add eax,ecx
		DEC eCX
		CMP eCX , 0
		JNE summa
	MOV res32, eax
	;printConsoleInt res
	;================Продолжаем расчет для вещественных===============
	mov ecx, BSIZE
	finit
	fld ex10c1
	fld ex10c2
	fsub st(0), st(1)
	fld res10
	fwait
	;push offset tpt
	;push offset res10
	;call crt_printf
	;invoke	crt_printf, ADDR tpt, res10
	;;=================Выход=======================
	
	push 0
	call ExitProcess
	
	;Процедура вывода разделителя
	print_endline proc
		lea eax, razdelit
		push eax
		lea ebx, formatStr
		push ebx
		call printf
		pop ebx					;очистка стека
		pop eax					;очистка стека
		ret
	print_endline endp
	
	print_Newline proc
		lea eax, endline
		push eax
		lea ebx, formatStr
		push ebx
		call printf
		pop ebx					;очистка стека
		pop eax					;очистка стека
		ret
	print_Newline endp
	
	;Процедура вывода целого 32-разрядного числа
	print_int proc
		push ebp						;регистр с параметрами процедуры
		mov ebp, esp					;вершина стека, где лежат процедуры
		mov eax, dword ptr [ebp + 8]	;первый параметр
		push eax						;грузим в стек для вызова printf
		lea ebx, formatInt
		push ebx
		call printf
		pop ebx					;очистка стека
		pop eax
		pop ebp
		ret 4
	print_int endp
	
	;Процедура печати 16-тиразрядного числа
	print_short proc	
		push ebp						;регистр с параметрами процедуры
		mov ebp, esp					;вершина стека, где лежат процедуры
		mov ax, word ptr [ebp + 8]		;первый параметр
		push dopres16
		push ax							;грузим в стек для вызова printf
		lea ebx, formatShort
		push ebx
		call printf
		pop ebx							;очистка стека
		pop eax							;выгрузить необходимо 32-разрядное число
		pop ebp
		ret 2
	print_short endp
end start
